home *** CD-ROM | disk | FTP | other *** search
-
- SiFLyiNG
- Tutorial #11
-
- ____________________________________________________________________________
-
- Target : webm4sta Crackme v1.0
- d/l it on http://crackmes.cjb.net
- Protection type : VB crackme, serial/name
- Level : really don't know :)
- Tools needed : Smatcheck for serial
- Smartcheck/SoftIce for Keygen
- A brain (optional for serial only)
- Some punk music, i.e. Bad Religion or NOFX today ;)
-
- ____________________________________________________________________________
-
- Before beginning...
-
- This crackme is coded in VB5. If you read the nfo, you'll see:
- "Rules: Takeout NAG Screen and hunt a serial # down *OR* make keygen." In
- this tut we'll see the last 2 parts (serial & keygen) only. The reason is that
- i was not able to takeout the nag, and i really wonder if it's possible,
- because the nag is the main form of the crackme and is called by ThunRTMain.
- I think i've told enough as introduction, so we must be ready to start...
-
- ____________________________________________________________________________
-
- The essay...
-
- 1. The serial
-
- First of all, i suppose you've correctly setup Smartcheck, because
- this is not the aim of the crackme. If it's not the case, just look for EB
- tutorial on Smartcheck.
- So, let's fire up Smartcheck, open the VBCrcMe1.exe and select start.
- There you should see the nag, which says 'NAG - Unregistered'. Let's press
- the ok button, and a new form is shown, with two textbox, one for the name,
- the other for the Serial.
- There type 'SiFLyiNG' in the first one, and '12345678' in the second
- one. Press the 'OK' button and what do you see :
- "Error"
- "Error: Invalid Serial"
- "MuHAHA, Try Again"
- It seems that '12345678' is not the valid serial here :)
-
- From there you return to Smartcheck. Select -if it's not already
- done- 'Show errors and specific events' in the View program. This will limit
- the informations that appear in the main left window.
- Just have a look at this window. We see:
-
- Command1 (CommandButton) created
- Label1 (Label) created
- + Command1_Click
- + CmdOK(0)_Click
-
- OK, let's explain all these lines :
-
- Command1 (CommandButton) created : the OK button of the nag has been created
- Label1 (Label) created : the label with the 'NAG' caption on the NAG has been
- created
-
- + Command1_Click : here you have clicked on the button called Command1 which
- is actually the OK button of the NAG form.
-
- NB : If you click on the + sign near the Command1_Click event in order to
- expand the thread, you'll see what this action (called 'event' in VB
- has made : Form1.Hide (hide the nag), CmdExit(1) (CommandButton) created,
- CmdOK(0) (CommandButton) created, TextSerial (Textbox) created... and
- finally Form2.Show which load the Registration Form.
-
- But this part is not interesting... let's have a look at the
- CmdOK(0)_Click. This will show us the CmdOK(0)_Click procedure. So click on
- + sign to open up the threads and you see that :
-
- - CmdOK(0)_Click
- TextName.Text
- Val(String:"SiFLyiNG") returns double:0
- Double(0) --> String("0")
- TextSerial.Text
- Val(String:"12345678") returns double: 1.23457e+007
- Double(1.123457) --> String("12345678")
- Len(String:"0") returns LONG:1
- Str(VARIANT:Double:1.45236e+009)
- String("1452356358") --> Double(1.45236e+009)
- TextSerial.Text
- String("12345678") --> Double(1.123457e+007)
- Command1 (CommandButton) created
- Label1 (Label) created
- Form3.Show
-
- We have here all the necessary to find the serial :
-
- String("1452356358") --> Double(1.45236e+009) : what's that ?
- TextSerial.Text
- String("12345678") --> Double(1.123457e+007) : the entered serial
-
- Hummm... i think it's clear. Type '1452356358' instead of our dummy
- serial, press the OK button and: "Great job"
- OK, we find a serial. Now let's try to keygen it...
-
- 2. The keygen
-
- 2.a) Smartcheck
-
- What we found with Smartcheck is enough to find the valid serial, but
- not to keygen this crackme. Let's resume what we know just with Smartcheck :
-
- Val(String:"SiFLyiNG") returns double:0
-
- Val function: returns the numbers contained in a string as a numeric
- value of appropriate type (here a double), i.e.:
- Val("1234") returns 1234
- Val("5 6 78") returns 5678
- Val("Toto") returns 0
- Val("123AZERTY") returns 123
-
- So you easily deduce that this function returns 0 when any name which
- doesn't begin with a number is entered. Moreover you'll see that the serial
- is the same for any name which doesn't begin with a number different from 0.
-
- Then you see that :
-
- Double(0) --> String("0")
-
- The returned value of the Val function is converted to a string with
- Str function.
-
- TextSerial.Text
- Val(String:"12345678") returns double: 1.23457e+007
- Double(1.123457) --> String("12345678")
-
- These lines aren't interesting for the keygen. The crackme gets the
- entered serial, converts it to a double, and reconverts it to a string.
-
- Len(String:"0") returns LONG:1
-
- The Len function returns the lenght of a string. Here it returns the
- lenght of the previous 0 converted to "0", that was returned by the Val
- function.
- That's why it returns 0.
-
- Str(VARIANT:Double:1.45236e+009)
-
- There we can suppose that the 1 has been transformed to the double
- 1.45236e+009, that is here converted to the string "1452356358", which is the
- valid serial.
-
- String("1452356358") --> Double(1.45236e+009)
-
- Hummm... Smartcheck has shown us lots of step of the routine that
- generates the valid serial, but this is not enough, because we don't know
- where the final serial come from ! That's why we'll now use SoftIce.
-
-
- The crackme converts another time the string to a double to finally
- make a comparison with the serial.
-
- 2.b) SoftIce
-
- OK, that's great to use SoftIce, but you surely wonder how we could
- do to break exactly in the generation routine. What don't we find an
- interesting breakpoint ? To do such a thing, you can use either WinDasm and
- select the import in the Functions menu, or a program called Exescope and
- the import in the left window. From there we have to find the most interesting
- function.
- Hummm... we see :
- __vbaLenBstr (returns the lenght of a string)
- rtcR8ValFromBstr (i suppose it's the Val function)
- I propose to choose the __vbaLenBstr function which returns 1 when
- the entered name is 'SiFLyiNG'. So make:
- 'Bpx __vbaLenBstr' in SoftIce, come back to the crackme and press 'OK'
- Boom... you're back in SoftIce and you see in the bottom:
-
- 'Break due to Msvbvm50!__vbaLenBstr'
-
- So you press F11 to returns to the caller (in the crackme code) and
- you should see:
-
- :0040659E Call dword ptr [MSVBVM50!__vbaLenBstr] ; returns 1 in EAX
- :004065A4 imul eax, 0000000C ; eax=eax*0xC=eax*12=1*12=12
- :004065A7 jo 004067F8 ; jmp if overflow
-
- Yes!!! we are just where we wanted to go :) Let's see what happens
- after that :
-
- :004065AD mov dword ptr [ebp-0084], eax ; stores eax=0xC in [ebp-84]
- :004065B3 lea ecx, dword ptr [ebp-3C]
- :004065B6 fild dword ptr [ebp-0084]
-
- NB: there you should see the toggle floating point stack window in Softice. If
- it's not the case, just press wf.
-
- The fild (integer load) instruction converts a 16,32 or 64 bit two's complement
- integer to the 80 bits extended precision format and pushes the result onto
- stack. I advise you to read the chapter 14 of the Art Of Assembly available
- on the net. It deals with FPU instructions you can meet in some protections.
-
- So, what is line has done is to convert the Dword at the address pointed by
- [ebp-84] into a Real8 and pushes the result on the FPU. You can see the data
- in the toggle floating point stack window :
-
- here we have st0 = 12
-
- Hey ! it's the 12=0xC that we was previously calculated by: 1*0xC
- So we can go on tracing: we're on the good way :)
-
- :004065BC lea edx, dword ptr [ebp-4C]
- :004065BF push ecx
- :004065C0 push edx
- :004065C1 mov [ebp-3C], 00000005
- :004065C8 fstp Real8 ptr [ebp-8C]
-
- * The FSTP instruction copy the value on the top of the floating point
- register (st0) to another floating points register or to a 32, 64 or 80
- bit memory variable (it's the case here).The FSTP instruction pops the value
- off the top of stack when moving it to the destination location. That's the
- reason why st0 is empty now.
-
- :004065CE fld Real8 ptr [ebp-8C]
-
- * The FLD instruction loads a 32 bit, 64 bit, or 80 bit floating point value
- (it's the case here) onto the stack.
- So we have here : st0 = 12
-
- :004065D4 cmp dword ptr [00407000], 00000000
- :004065DB jne 004065E5 : this jump is not taken
- :004065DD fdiv Real8 ptr [00401010]
-
- * The fdiv instruction computes the following quotient:
- st0 = st0 / 80 bit floating point value at [401010]
-
- Wtf ??? how do we know this 80 bit value ? Hummm... i have one method,
- very intuitive : to divide the previous st0 with the result of the fdiv.
-
- Here, the result is 6. So the value was 12/6=2 !!! This is very
- important to keygen !
-
- :004065E3 jmp 004065F6
-
- Let's see where we land after the jump :
-
- :004065F6 fsub Real8 ptr [00401018]
-
- Ok i suppose you understand what this instruction make. Here the result is:
-
- st0 = 1452356358 hey ! it looks like the serial ;)
-
- Let's reverse it in order to see the value of the 80 bit value
- stored at [00401018] :
-
- 6-X = 1452356358 <=> X = -1452356358+6 = -1452356352
-
- Now we have all that is necessary to write a keygen for this crackme. But for
- those who are curious and wonder how the entered serial and the valid serial
- are compared, just trace a bit until you land here:
-
- :00406662 mov eax, dword ptr [ebp-28] ; eax points to the entered serial
- ; in wide characters (1.2.3.4.5.6.7.8.)
- :00406665 push eax ; push the mem location of the entered
- ; serial
- :00406666 Call dword ptr [MSVBVM50!__vbaR8Str] ; converts the string stored
- ; in the last pushed location (here
- ; it was eax) into a 80 bit value
- :0040666C fcomp Real8 ptr [ebp-24]
-
- Here [ebp-24] points to the 80 bit value of the valid serial. So this
- instruction makes a comparison.
-
- * With a 80 bit memory operand, the Fcomp instruction compare the memory
- variable against st0, setting the condition code bits accordingly. Fcomp
- also pops st0 after the comparison.
-
- :0040666F fstsw ax ; return ax=4000h if they are equal
- :00406671 test ah, 40 ; test if equal
- :00406674 je 0040667D ; jump to "great job" if they are equal
- :00406676 mov esi, 00000001
- :0040667B jmp 0040667F ; otherwise, jump to "Invalid serial"
-
- Waouhhh !!! it's almost finished :P
- Let's summarize the keygen routine now :
-
- 1. Takes the value of the entered string : Val(UserName)
- 2. Convert it to a string: Str(Val(Username)
- i advise to add Trim to avoid getting space in front of the string,
- because w could get an error otherwise.
- so Trim(Str(Val(UserName)))
- 3. Gets the len of this string: Len(Trim(Str(Val(UserName))))
- 4. Multiply it with 12 and divide it with 2
- so it multiplies it with 6:
- Len(Trim(Str(Val(UserName)))) * 6
- 5. Finally substract -1452356352 to this value
- so it add 1452356352:
-
- Serial = Len(Trim(Str(Val(UserName)))) * 6 + 1452356352
-
- ___________________________________________________________________________
-
- The end...
-
- Voila, it's finished: crackme cracked, keygened too :) I've tried
- to make this tut as understandable as i could. I hope you've read it entirely
- and enjoyed it over all !!! I've writed enough for today so i won't make a big
- conclusion. But if you have questions, critics, suggestions, just mail me.
-
- SiFLyiNG
- siflying@ifrance.com
-
- Greetz : ACiD BuRN, Magic Raphoun, Lucifer48, Eternal Bliss, AB4DS
- Volatility, VisionZ, Liquid, Skymarshall, webm4sta, Fireworks
- and all the authors of crackmes and tutorials
-
-
-
-